/**
 * 
 */
define(function(){
	var m_guid = '',
		m_socketconnected = false,
		m_serverconnected = false,
		m_registered = false,
		m_recordstarted = false;
	var RecordingRequestID={
		EVT_APIREGISTERREQ:131073,
		EVT_APIREGISTERED:131074,
		EVT_APIUNREGISTERREQ:131075,
		EVT_APIUNREGISTERED:131076,
		EVT_APIDISCONNECTED:131077,
		EVT_APISTARTRECORDREQ:131078,
		EVT_APISTOPRECORDREQ:131079,
		EVT_APIUPDATERECORDREQ:131080,
		EVT_APICUSTOMREQ:131081,
		EVT_APIGETSTATEREQ:131082,
		EVT_APIGETSTATERESP:131083,
		EVT_RECORDERRECORDINGSTOPPED:1048592, //定义多了一个0，将错就错了
		EVT_RECORDERRECORDINGSTOPFAIL:65553,
		EVT_RECORDERRECORDINGSTARTED:65543,
		EVT_RECORDERRECORDINGSTARTFAIL:65544

	};
	var _timer_keepalive = 0;
	var _timer_keepalive_count = 0;
	var _timer_gap = 0;
	var m_StartRecordOnIB = 0;
	var m_StartRecordOnOB = 0;
	var extr = {};

	var m_timer = new Worker($E.softphoneBasePath + "/softphone/webworker_timer.min.js");
	var m_timerCallers = {};
	m_timer.onmessage = function(event) {
		//console.log("softphone.core.timer", JSON.stringify(event.data));
		var timer = event.data.timer;
		if (event.data.eventtype === "timer") {
			if (m_timerCallers[timer.timerUUID] && m_timerCallers[timer.timerUUID].callback) {
				var newdate = new Date().valueOf();
				_timer_gap = newdate - m_timerCallers[timer.timerUUID].time;
				m_timerCallers[timer.timerUUID].time = newdate;
				m_timerCallers[timer.timerUUID].callback(timer.count, _timer_gap, timer.time);
			}
		}
		if (event.data.eventtype === "timerStart") {
			//console.log("ctiextra_eliterecord.startTimer", timer.UUID, timer.timerId, timer.timerName, timer.interval);
			$SC.addconsolelog("ctiextra_eliterecord.startTimer" + ", " + timer.timerUUID + ", " + timer.timerId + ", " + timer.timerName + ", " + timer.interval);
			m_timerCallers[timer.timerUUID].timerId = timer.timerId;
		}
		if (event.data.eventtype === "timerEnd") {
			//console.log("ctiextra_eliterecord.stoptTimer", timer.UUID, timer.timerId, timer.timerName, timer.interval);
			$SC.addconsolelog("ctiextra_eliterecord.stoptTimer" + ", " + timer.timerUUID + ", " + timer.timerId + ", " + timer.timerName + ", " + timer.interval);
			delete m_timerCallers[timer.timerUUID];
		}
	};

	var startTimer = function(interval, countlimit, startcount, timerName, callback) {
		if (m_timer) {
			var timerUUID = Guid.raw();
			m_timerCallers[timerUUID] = {};
			m_timerCallers[timerUUID].timerUUID = timerUUID;
			m_timerCallers[timerUUID].timerName = timerName;
			m_timerCallers[timerUUID].callback = callback;
			m_timerCallers[timerUUID].time = new Date().valueOf();
			m_timer.postMessage({
				"method":"startTimer"
				, "params":{"timerName": timerName
					,"interval": interval
					, "countlimit": countlimit
					, "startcount": startcount
					, "timerUUID": timerUUID
				}
			});
			return timerUUID;
		} else {
			console.warn("ctiextra_eliterecord.startTimer, no timer worker");
		}
	};

	var stopTimer = function(timerUUID, timerId, timerName) {
		if (m_timer) {
			if (timerUUID && m_timerCallers[timerUUID]) {
				if (!timerId) {
					timerId = m_timerCallers[timerUUID].timerId;
				}
				if (!timerName) {
					timerName = m_timerCallers[timerUUID].timerName;
				}
			}
			var timerId = m_timer.postMessage({"method":"stopTimer", "params":{"timerUUID": timerUUID, "timerId": timerId,"timerName": timerName}});
		}
	};

	var Extra = function(project){
		extr.project = project;
		extr.name = 'ctiextra_eliterecord';
		$SC.addEvtListener(extr.name, 'OnSCTIEvent', OnSCTIEvent, -1);
	}
	Extra.prototype = {		
		queryCTICall : function(){
			
		}
	}

	Extra.connectrecserver = function(serverendpoint)
	{
		if (serverendpoint) {
			extr.serverendpoint = serverendpoint;
		}
		$SC.addconsolelog("::ctiextra_eliterecord: websocket " + extr.serverendpoint);
		extr.websocket=new WebSocket(extr.serverendpoint);
		extr.websocket.onopen=function(evt){
			$SC.addconsolelog('::ctiextra_eliterecord: socket connected');
			m_socketconnected = true;
			_timer_keepalive_count = 0;
			/*
			_timer_keepalive = setTimeout(function() {
				Extra.keepalive();
				_timer_keepalive = setTimeout(arguments.callee,5000);
			}, 5000);
			 */
			startTimer(_timer_keepalive, 0,0,"recordkeepalive",function(counter, gap, time){
				Extra.keepalive();
			})
		};
		extr.websocket.onclose=function(evt){
			$SC.addconsolelog('::ctiextra_eliterecord: socket disconnected');
			m_socketconnected = false;
			/*
			if (_timer_keepalive) {
				clearTimeout(_timer_keepalive);
				_timer_keepalive = 0;
			}
			 */
			stopTimer("","","recordkeepalive");

			//if ($SC.agentState > 1 && !extr.m_tmr_connect) {
			if ($SC.agentState > 1) {
				$SC.addconsolelog('::ctiextra_eliterecord: try to reconnect after 5000 miniseconds');
				extr.m_connect = 1;
				//extr.m_tmr_connect = setInterval(function(){
				//setTimeout(function(){
				startTimer(5000,1,0,"recordreconnect",function(counter, gap, time) {
					if (!extr.m_connect) {
						$SC.addconsolelog('::ctiextra_eliterecord: no reconnect for m_connect = ' + extr.m_connect);
						return;
					}
					extr.m_connect = 0;
					if ($SC.agentState > 1) {
						//CONNECTING OPEN CLOSING或CLOSED
						if (extr.websocket.readyState == 3) {
							$SC.addconsolelog('::ctiextra_eliterecord: try to reconnect now');
							Extra.connectrecserver();
						} else {
							$SC.addconsolelog('::ctiextra_eliterecord: not reconnect for websocket.readyState = ' + extr.websocket.readyState.toString());
						}
					} else {
						/*
						if (extr.m_tmr_connect > 0) {
							clearInterval(extr.m_tmr_connect);
							extr.m_tmr_connect = 0;
						}
						 */
						$SC.addconsolelog('::ctiextra_eliterecord: no reconnect for cti logout');
					}
				})
				//}, 5000)
			}
		}
		extr.websocket.onmessage=function(evt){
			extr.OnRecordingEvent(evt);
			//onMessage(evt);
		}
		extr.websocket.onerror=function(evt){
			$SC.addconsolelog('::ctiextra_eliterecord: socket Error ' + JSON.stringify(evt));
			//onError(evt);
		}
	}
	Extra.RegisterExtension = function(DN)
	{
		extr.dn=DN;
		var request = {
			request: {type: 1, value: 11111},
			recevent: {type: 1, value: RecordingRequestID.EVT_APIREGISTERREQ},
			extension: {type: 3, value: DN}
		}
		$SC.addconsolelog('::ctiextra_eliterecord register ' + DN);
		extr.websocket.send(JSON.stringify(request));
	}

	Extra.UpdateData=function(rec_guid, datas)
	{
		var request = {
			request: {type:1, value: 11111},
			recevent: {type:1, value: RecordingRequestID.EVT_APIUPDATERECORDREQ},
			recchannelid : {type:1, value: extr.channelid},
			extension: {type:3, value: extr.dn},
			rec_guid: {type: 3, value: rec_guid}
		};
		if (typeof(datas) == 'string') {
			request = JSON.stringify(request+',"apidatas":{"type":5, "value":"'+datas+'"}');
			$SC.addconsolelog('::ctiextra_eliterecord, updatedata ' + datas);
		} else {
			request.apidatas = {type: 5, value: datas};
			request = JSON.stringify(request);
			$SC.addconsolelog('::ctiextra_eliterecord, updatedata ' + JSON.stringify(datas));
		}
		extr.websocket.send(request);
	}

	Extra.StartRecord = function()
	{
		var request = {
			request: {type:1, value: 11111},
			recevent: {type:1, value: RecordingRequestID.EVT_APISTARTRECORDREQ},
			recchannelid : {type:1, value: extr.channelid},
			thisdn: {type:3, value: extr.dn},
			projectid: {type: 3, value: extr.project.id}
		};
		$SC.addconsolelog('::ctiextra_eliterecord, startrecord');
		extr.websocket.send(JSON.stringify(request));
	}

	Extra.StopRecord = function()
	{
		var request = {
			request: {type:1, value: 11111},
			recevent: {type:1, value: RecordingRequestID.EVT_APISTOPRECORDREQ},
			recchannelid : {type:1, value: extr.channelid},
			thidn: {type:3, value: extr.dn}
		};
		$SC.addconsolelog('::ctiextra_eliterecord, stoprecord');
		extr.websocket.send(JSON.stringify(request));
	}

	Extra.keepalive = function()
	{
		var request = {
			//request: {type:1, value: 11111},
			request: {type:1, value: 0},
			recevent: {type:1, value: 0},
			recchannelid : {type:1, value: extr.channelid},
			thisdn: {type:3, value: extr.dn},
			projectid: {type: 3, value: extr.project.id}
		};
		_timer_keepalive_count++;
		//console.log('::ctiextra_eliterecord, keepalive', _timer_keepalive_count, _timer_gap);
		$SC.addconsolelog('::ctiextra_eliterecord, keepalive' + ", " + _timer_keepalive_count + ", " + _timer_gap);
		extr.websocket.send(JSON.stringify(request));
	}

	extr.OnRecordingEvent = function(evt) {
		$SC.addconsolelog('::ctiextra_eliterecord, OnRecordingEvent ' + evt.data);
		var datas=eval('('+evt.data+')');
		if(typeof datas.recevent!='undefined'){
			var evt=parseInt(datas.recevent.value);
			switch(evt)	{
			case RecordingRequestID.EVT_APIREGISTERED:
				extr.channelid=parseInt(datas.recchannelid.value);
				if (m_StartRecordOnIB > 0 || m_StartRecordOnOB >0) {
					let callstate2 = $SC.CallInfo.CallState2;
					if (callstate2 > 0) {
						$SC.addconsolelog("::ctiextra_eliterecord, fake OnCallxx after EVT_APIREGISTERED");
						if (callstate2 == 1 || callstate2 == 4) {
							OnSCTIEvent("OnCallStart");
						} else {
							OnSCTIEvent("OnCallEstablish");
						}
					}
				}
				break;
			case RecordingRequestID.EVT_RECORDERRECORDINGSTARTED:
				m_guid = datas.rec_guid.value;
				$SC.setRecordInfo({recording_guid : m_guid, recording_state : 1, recording_file : ''});
				break;
			case RecordingRequestID.EVT_RECORDERRECORDINGSTOPPED:
				$SC.setRecordInfo({recording_guid : m_guid, recording_state : 0, recording_file : ''});
				break;
			case RecordingRequestID.EVT_APIUNREGISTERED:
			case RecordingRequestID.EVT_APIDISCONNECTED:
				break;
			}
		}else if(typeof datas.event!='undefined'){
			var evt=parseInt(datas.event.value);
			if(evt==12){
				//此时才是真正连上了服务器，可以发送register请求
				Extra.RegisterExtension($SC.dn);
			}
		}
	}
	function OnSCTIEvent(evt){
		switch(evt.toLowerCase()){
		case 'onlogin':
			m_StartRecordOnIB = $SC._getconfig("RECORD", "StartRecordOnIB");
			m_StartRecordOnOB = $SC._getconfig("RECORD", "StartRecordOnOB");
			_timer_keepalive = $SC._getconfig("RECORD", "RecordKeepAlive") || 30000;

			var recsrv = $SC.commonCall("getinivalue", "[RECORD]recserver");
			if (!recsrv) {
				$SC.addconsolelog('::ctiextra_eliterecord: got no [RECORD]recserver config');
				return;
			}
			$SC.addconsolelog('::ctiextra_elitecord: connectrecserver ' + recsrv);
			//if (extr.m_tmr_connect) {
			//	clearInterval(extr.m_tmr_connect);
			//	extr.m_tmr_connect = 0;
			//}
			extr.m_connect = 0;
			Extra.connectrecserver(recsrv);
			break;
		case 'onlogout':
			if (m_socketconnected) {
				$SC.addconsolelog('::ctiextra_eliterecord: websocket.close()');
				//if (extr.m_tmr_connect) {
				//	clearInterval(extr.m_tmr_connect);
				//	extr.m_tmr_connect = 0;
				//}
				extr.m_connect = 0;
				extr.websocket.close();
			}
			break;
		case 'oncallstart':
			m_guid = '';

			if ((m_StartRecordOnIB == 1 && m_StartRecordOnOB == 1) || (m_StartRecordOnIB == 1 && $SC.CallInfo.CallType == 2) || (m_StartRecordOnOB == 1 && $SC.CallInfo.CallType != 2)) {
				Extra.StartRecord();
			}

			break;
		case 'oncallestablish':
			//Extra.StartRecord();
			if ((m_StartRecordOnIB == 2 && m_StartRecordOnOB == 2) || (m_StartRecordOnIB == 2 && $SC.CallInfo.CallType == 2) || (m_StartRecordOnOB == 2 && $SC.CallInfo.CallType != 2)) {
				Extra.StartRecord();
			}
			break;
		case 'oncallend':
			if (m_guid) {
				Extra.StopRecord();
			}
			//break;
		case 'saveevent':
			if (m_guid) {
				if (evt.toLowerCase() == "oncallend" && $SC.CallInfo.EstablishTime) {
					break;
				}
				var datas = {};
				datas.MProject_ID = extr.project.id;
				if (datas.MProject_ID) {
					if (datas.MProject_ID.length>6) {
						datas.MProject_ID = datas.MProject_ID.substr(0, 6);
					} 			
				} else {
					delete datas.MProject_ID;
				}
				datas.STAFF_ID = {type: 3, value: $SC.CallInfo.m_Event.handleby_id};
				datas.RoleGroup_ID = {type: 3, value: $SC.CallInfo.m_Event.handlegroup_id};
				datas.Event_GUID = {type: 3, value: $SC.CallInfo.m_Event.event_guid};
				datas.Customer_GUID = {type: 3, value: $SC.CallInfo.m_Event.customer_guid};
				if (!datas.Customer_GUID || datas.Customer_GUID == 'undefined') {
					datas.Customer_GUID = '';
				}
				datas.CustomerName = {type: 3, value: $SC.CallInfo.m_Event.customername};
				Extra.UpdateData(m_guid, datas);
			}
			break;
		}
	}
	return Extra; 
});

